package com.liuhuanss.sheep.service;

import com.liuhuanss.sheep.model.GameBlock;
import com.liuhuanss.sheep.model.GameState;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class GameService {
    
    private final Map<String, GameState> games = new ConcurrentHashMap<>();
    
    // 可用的方块类型
    private final String[] BLOCK_TYPES = {
        "兔子", "刷子", "剪刀", "南瓜", "奶瓶", "帽子", "干草", "手套", 
        "月饼", "树", "树桩", "栗子", "毛线", "水桶", "火堆", "白菜", 
        "耙子", "苹果", "草", "萝卜", "蜜蜂", "酒坛", "铃铛", "面具", "饭团"
    };

    public GameState createNewGame(String gameId) {
        GameState gameState = new GameState(gameId);
        generateBlocks(gameState);
        games.put(gameId, gameState);
        return gameState;
    }

    public GameState getGame(String gameId) {
        return games.get(gameId);
    }

    private void generateBlocks(GameState gameState) {
        List<GameBlock> blocks = new ArrayList<>();
        Random random = new Random();
        
        // 生成多层方块，确保每种类型的方块数量是3的倍数
        int totalBlocks = 60; // 总方块数
        int typesCount = 20; // 使用的类型数量
        
        List<String> blockTypesList = new ArrayList<>();
        for (int i = 0; i < typesCount; i++) {
            String type = BLOCK_TYPES[i % BLOCK_TYPES.length];
            // 每种类型生成3个
            for (int j = 0; j < 3; j++) {
                blockTypesList.add(type);
            }
        }
        
        // 打乱顺序
        Collections.shuffle(blockTypesList);
        
        // 生成方块位置
        int blockIndex = 0;
        for (int layer = 0; layer < 4; layer++) {
            for (int y = 0; y < 5; y++) {
                for (int x = 0; x < 3; x++) {
                    if (blockIndex < blockTypesList.size()) {
                        String blockId = "block_" + blockIndex;
                        String type = blockTypesList.get(blockIndex);
                        GameBlock block = new GameBlock(blockId, type, x, y, layer);
                        blocks.add(block);
                        blockIndex++;
                    }
                }
            }
        }
        
        gameState.setBlocks(blocks);
        updateClickableBlocks(gameState);
    }

    public GameState clickBlock(String gameId, String blockId) {
        GameState gameState = games.get(gameId);
        if (gameState == null || gameState.isGameOver()) {
            return gameState;
        }

        GameBlock clickedBlock = gameState.getBlocks().stream()
                .filter(block -> block.getId().equals(blockId) && block.isClickable() && !block.isRemoved())
                .findFirst()
                .orElse(null);

        if (clickedBlock == null) {
            return gameState;
        }

        // 将方块添加到槽位
        boolean added = addToSlots(gameState, clickedBlock.getType());
        if (added) {
            clickedBlock.setRemoved(true);
            updateClickableBlocks(gameState);
            checkGameStatus(gameState);
        }

        return gameState;
    }

    private boolean addToSlots(GameState gameState, String blockType) {
        List<String> slots = gameState.getSlots();
        
        // 查找空槽位
        for (int i = 0; i < slots.size(); i++) {
            if (slots.get(i) == null) {
                slots.set(i, blockType);
                
                // 检查是否有3个相同的可以消除
                checkAndRemoveMatches(gameState);
                return true;
            }
        }
        
        // 槽位满了，游戏结束
        gameState.setGameOver(true);
        return false;
    }

    private void checkAndRemoveMatches(GameState gameState) {
        List<String> slots = gameState.getSlots();
        Map<String, List<Integer>> typePositions = new HashMap<>();
        
        // 统计每种类型的位置
        for (int i = 0; i < slots.size(); i++) {
            String type = slots.get(i);
            if (type != null) {
                typePositions.computeIfAbsent(type, k -> new ArrayList<>()).add(i);
            }
        }
        
        // 查找有3个或更多相同类型的
        for (Map.Entry<String, List<Integer>> entry : typePositions.entrySet()) {
            if (entry.getValue().size() >= 3) {
                // 移除前3个
                List<Integer> positions = entry.getValue();
                for (int i = 0; i < 3; i++) {
                    slots.set(positions.get(i), null);
                }
                
                // 整理槽位，将非空的向前移动
                compactSlots(gameState);
                
                // 增加分数
                gameState.setScore(gameState.getScore() + 100);
                
                // 递归检查是否还有可消除的
                checkAndRemoveMatches(gameState);
                break;
            }
        }
    }

    private void compactSlots(GameState gameState) {
        List<String> slots = gameState.getSlots();
        List<String> nonNullSlots = new ArrayList<>();
        
        for (String slot : slots) {
            if (slot != null) {
                nonNullSlots.add(slot);
            }
        }
        
        // 重新填充槽位
        for (int i = 0; i < slots.size(); i++) {
            if (i < nonNullSlots.size()) {
                slots.set(i, nonNullSlots.get(i));
            } else {
                slots.set(i, null);
            }
        }
    }

    private void updateClickableBlocks(GameState gameState) {
        List<GameBlock> blocks = gameState.getBlocks();
        
        // 重置所有方块的可点击状态
        for (GameBlock block : blocks) {
            if (!block.isRemoved()) {
                block.setClickable(true);
                
                // 检查是否被直接覆盖（只检查正上方的方块）
                for (GameBlock otherBlock : blocks) {
                    if (!otherBlock.isRemoved() && 
                        otherBlock.getLayer() < block.getLayer() &&
                        otherBlock.getX() == block.getX() &&
                        otherBlock.getY() == block.getY()) {
                        block.setClickable(false);
                        break;
                    }
                }
            }
        }
    }

    private void checkGameStatus(GameState gameState) {
        List<GameBlock> remainingBlocks = gameState.getBlocks().stream()
                .filter(block -> !block.isRemoved())
                .collect(Collectors.toList());
        
        if (remainingBlocks.isEmpty()) {
            gameState.setGameWon(true);
            gameState.setGameOver(true);
            return;
        }
        
        // 检查是否有可点击的方块
        boolean hasClickableBlocks = remainingBlocks.stream()
                .anyMatch(GameBlock::isClickable);
        
        // 检查槽位是否快满了且没有可消除的组合
        List<String> slots = gameState.getSlots();
        long nonNullSlots = slots.stream().filter(Objects::nonNull).count();
        
        if (!hasClickableBlocks || (nonNullSlots >= 7)) {
            // 检查是否还有可消除的组合
            Map<String, Integer> typeCounts = new HashMap<>();
            for (String slot : slots) {
                if (slot != null) {
                    typeCounts.put(slot, typeCounts.getOrDefault(slot, 0) + 1);
                }
            }
            
            boolean hasMatch = typeCounts.values().stream().anyMatch(count -> count >= 3);
            if (!hasMatch && nonNullSlots >= 6) {
                gameState.setGameOver(true);
            }
        }
    }
}